﻿
Imports std

Namespace internalFunctions

    'parameters, o, output
    'output, bool, whether output is success or not
    Public Class writeConsole
        Inherits internalFunction

        Public Class parameters
            Public Const o As String = "o"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialSerialMapping(m, parameters.o)
        End Sub

        Public Sub New()
            Me.New("console.write")
        End Sub

        Protected Sub New(ByVal name As String)
            MyBase.New(name, m)
        End Sub

        Protected Overridable Sub write(ByVal o As String)
            Console.Write(o)
        End Sub

        Private Function findvariablesCB(ByVal name As String, ByVal var As String, _
                                         ByRef __NOT_IN_USE__ As Object) As Boolean
            write(var)
            Return True
        End Function

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim rtn As Boolean
            rtn = ctx.findVariables(AddressOf findvariablesCB, string_finder(), parameters.o)
            If Not rtn Then
                'make it compatible with existing scripts
                Dim var As String = Nothing
                rtn = ctx.findVariableStr(parameters.o, var) AndAlso findvariablesCB(Nothing, var, Nothing)
            End If
            output = New bare_variable(typeDefination.bool, True)
            Return True
        End Function
    End Class

    'parameters, same as console.write
    'return, same as console.write
    Public Class writeConsoleLine
        Inherits writeConsole

        Public Sub New()
            MyBase.New("console.writeline")
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            If MyBase.invoke(ctx, output) Then
                Console.WriteLine()
                Return True
            Else
                Return False
            End If
        End Function
    End Class

    'parameters, i, pointer<string> or var
    'output, bool, whether reading is success or not
    Public Class readConsole
        Inherits internalFunction

        Public Class parameters
            Public Const i As String = "i"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.i)
        End Sub

        Public Sub New()
            MyBase.New("console.read", m)
        End Sub

        Protected Overridable Function readline() As String
            Return Console.ReadLine()
        End Function

        Protected NotOverridable Overrides Function invoke(ByVal ctx As context, _
                                                           ByRef output As bare_variable) As Boolean
            Dim i As bare_variable = Nothing
            i = ctx.findVariable(parameters.i)
            If i Is Nothing Then
                raiseError("expect parameter " + parameters.i, errorHandle.errorType.user)
                Return False
            ElseIf Not i.variable().isPointerOfString() Then
                raiseError("expect parameter " + parameters.i + " is pointer of string or var.", _
                           errorHandle.errorType.user)
                Return False
            Else
                Dim rtn As String = Nothing
                rtn = readline()
                If Not rtn Is Nothing Then
                    If i.variable().elementType1() = typeDefination.string Then
                        convertor.cast(Of pointer(Of pointer(Of String)))(i.value()).instance().setinstance(rtn)
                    Else
                        convertor.cast(Of pointer(Of pointer(Of Object)))(i.value()).instance().setinstance(rtn)
                    End If
                    output = New bare_variable(typeDefination.bool, True)
                Else
                    output = New bare_variable(typeDefination.bool, False)
                End If

                Return True
            End If
        End Function
    End Class

    'parameters, N/A
    'return, a vector<string>, contains all commandline arguments
    Public Class consoleCommands
        Inherits noInputFunction(Of pointer(Of vector(Of String)))

        Public Sub New()
            MyBase.New("console.commands")
        End Sub

        Protected Overrides Function invoke(ByRef o As pointer(Of vector(Of String))) As Boolean
            If o Is Nothing Then
                o = New pointer(Of vector(Of String))()
            End If
            If +o Is Nothing Then
                o.setinstance(New vector(Of String)())
            Else
                o.instance().clear()
            End If

#If Not PocketPC AndAlso Not Smartphone Then
            o.instance().push_back(Environment.GetCommandLineArgs())
#End If
            Return True
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.vector
        End Function

        Protected Overrides Function elementType1() As typeDefination
            Return typeDefination.string
        End Function
    End Class

    'parameters, N/A
    'return, a map<string,string>, contains all commandline arguments
    Public Class consoleCommandsMapping
        Inherits noInputFunction(Of pointer(Of map(Of String, String)))

        Public Sub New()
            MyBase.New("console.commandsmapping")
        End Sub

        Protected Overrides Function invoke(ByRef o As pointer(Of map(Of String, String))) As Boolean
            If o Is Nothing Then
                o = New elpmis_map(Of String, String)()
            End If

            Dim m As map(Of String, vector(Of String)) = Nothing
#If Not PocketPC AndAlso Not Smartphone Then
            argmgr.parse(Environment.GetCommandLineArgs(), m)
#End If

            Dim it As map(Of String, vector(Of String)).iterator = Nothing
            it = m.begin()
            While it <> m.end()
                o.instance()((+it).first()) = (+it).second.ToString(character.blank)
                inc(it)
            End While

            Return True
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.map
        End Function

        Protected Overrides Function elementType1() As typeDefination
            Return typeDefination.string
        End Function

        Protected Overrides Function elementType2() As typeDefination
            Return typeDefination.string
        End Function
    End Class

    'parameters, N/A
    'return, a map<string,string>, contains all environments
    Public Class consoleEnvironments
        Inherits noInputFunction(Of pointer(Of map(Of String, String)))

        Public Sub New()
            MyBase.New("console.environments")
        End Sub

        Protected Overrides Function invoke(ByRef o As pointer(Of map(Of String, String))) As Boolean
            If o Is Nothing Then
                o = New elpmis_map(Of String, String)()
            End If

            Dim it As DictionaryEntry = Nothing
            Dim m As IDictionary = Nothing
#If Not PocketPC AndAlso Not Smartphone Then
            m = Environment.GetEnvironmentVariables()
#End If
            For Each it In m
                o.instance()(it.Key) = it.Value
            Next

            Return True
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.map
        End Function

        Protected Overrides Function elementType1() As typeDefination
            Return typeDefination.string
        End Function

        Protected Overrides Function elementType2() As typeDefination
            Return typeDefination.string
        End Function
    End Class

    'parameters, N/A
    'return, bool, success
    Public Class consolepause
        Inherits noInputFunction(Of Boolean)

        Public Sub New()
            MyBase.New("console.pause")
        End Sub

        Protected Overrides Function invoke(ByRef o As Boolean) As Boolean
            pause()
            o = True
            Return True
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.bool
        End Function
    End Class

    'parameters, command, any, convert to string, the command line
    '            wait, bool, optional, whether wait the command to finish, default value is false
    '            timeout, int, optional, use only when wait, the timeout to run the command,
    '                     default value is -1, means forever
    'return, int, process id
    Public Class exec
        Inherits internalFunction

        Public Class parameters
            Public Const command As String = "command"
            Public Const wait As String = "wait"
            Public Const timeout As String = "timeout"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.command, parameters.wait, parameters.timeout)
        End Sub

        Public Sub New()
            MyBase.New("exec", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim cmd As String = Nothing
            If ctx.findVariableStr(parameters.command, cmd) Then
                Dim wait As Boolean
                If Not ctx.findVariableBool(parameters.wait, wait) Then
                    wait = True
                End If
                Dim timeout As Int64
                If Not ctx.findVariableInt(parameters.timeout, timeout) Then
                    timeout = -1
                End If
                Dim rtn As Int32
                Try
                    rtn = Shell(cmd, AppWinStyle.NormalFocus, wait, timeout)
                Catch
                    rtn = npos
                End Try
                output = New bare_variable(typeDefination.int, Convert.ToInt64(rtn))
                Return True
            Else
                raiseError("expect parameter " + parameters.command, errorHandle.errorType.user)
                Return False
            End If
        End Function
    End Class

    'parameters, N/A
    'return, int, the key code
    Public Class consolereadkey
        Inherits noInputFunction(Of Int64)

        Public Sub New()
            MyBase.New("console.readkey")
        End Sub

        Protected Overrides Function invoke(ByRef o As Int64) As Boolean
#If Not PocketPC AndAlso Not Smartphone Then
            o = Console.Read()
#End If
            Return True
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.int
        End Function
    End Class
End Namespace
